﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows.Forms;
using DataAssociations.Repository.Connection.RDBMSSchemaExplorer;
using DataAssociations.Repository.Connection.RDBMSSchemaExplorer.Interfaces;
using DataAssociations.Repository.Queries;
using System.IO;

namespace DataAssociations
{
    public partial class AnalysisForm : Form
    {
        private readonly IDataRepository _dataRepository;
        private readonly string _databaseConnectionString;

        private readonly DrawForeignKeyGrid _drawForeignKeyDelegate;
        private readonly IRelationalSchemaExplorer _schemaExporter;
        private IList<TableForeignKeyData> _databaseMetadata;
        private Repository.Connection.RDBMSConnectionInterfaces.IConnectionStringType _connection;
        private OptionsFileReader _optionsFileReader;
        
        public AnalysisForm(Repository.Connection.RDBMSConnectionInterfaces.IConnectionStringType connection)
        {
            InitializeComponent();
            _connection = connection;
            _databaseConnectionString = connection.BuildConnectionString().ConnectionString;
            _schemaExporter = connection.GetSchemaExporter;
            _dataRepository = connection.GetDataRepository;
            _drawForeignKeyDelegate = FillData;
            groupBoxDataPrepare.Enabled = false;
            groupBoxAnalysis.Enabled = false;
            labelPleaseWait.Visible = true;
            buttonViewResults.Enabled = true;
            backgroundWorkerQuery.RunWorkerAsync();
        }

        internal void FillData(IList<TableForeignKeyData> foreignKeys)
        {
            _databaseMetadata = foreignKeys;
            groupBoxDataPrepare.Enabled = true;
            groupBoxAnalysis.Enabled = true;
            labelPleaseWait.Visible = false;
            comboBoxTables.DataSource = foreignKeys.Select(x => x.TableName).ToList();
            comboBoxTables.SelectedIndex = 0;
            comboBoxTransactions.DataSource = foreignKeys.First().ForeignKeys.ToList();
            comboBoxTransactionItems.DataSource = foreignKeys.First().ForeignKeys.ToList();
        }

        private void backgroundWorkerQuery_DoWork(object sender, DoWorkEventArgs e)
        {
            BeginInvoke(_drawForeignKeyDelegate,
                        _schemaExporter.BuildForeignKeyConstraintsForDatabase(_databaseConnectionString).ToList());
        }

        private void buttonSetUp_Click(object sender, EventArgs e)
        {
            var optionsForm = new OptionsForm();
            optionsForm.ShowDialog();
        }

        private void AnalysisForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            Application.Exit();
        }

        private void ChangeUI(bool disable)
        {
            buttonViewResults.Enabled = !disable;
            groupBoxDataPrepare.Enabled = !disable;
            groupBoxAnalysis.Enabled = !disable;
            labelPleaseWait.Visible = disable;
        }

        private void buttonStartAnalysis_Click(object sender, EventArgs e)
        {
            ChangeUI(true);
            //get data from database based on comboboxes selection
            if (comboBoxTransactions.SelectedValue.ToString() == comboBoxTransactionItems.SelectedValue.ToString())
            {
                MessageBox.Show("Transaction item and transaction holder must be different items");
                ChangeUI(false);
                buttonViewResults.Enabled = false;
                return;
            }            
            _optionsFileReader = new OptionsFileReader();
            _optionsFileReader.Options.DatabaseMetadata = new DatabaseMetadataOptions
                                                              {
                                                                  TableName = comboBoxTables.SelectedValue.ToString(),
                                                                  TransactionColumnName =
                                                                      comboBoxTransactions.SelectedValue.ToString(),
                                                                  TransactionItemColumnName =
                                                                      comboBoxTransactionItems.SelectedValue.ToString()
                                                              };

            var algorithmRunner = new AlgorithmRunner(_connection, _schemaExporter, _dataRepository);
            algorithmRunner.Run(_optionsFileReader.Options);
            ChangeUI(false);
        }

        private void comboBoxTables_SelectedIndexChanged(object sender, EventArgs e)
        {
            string selectedItemValue = comboBoxTables.SelectedValue.ToString();
            comboBoxTransactions.DataSource =
                _databaseMetadata.First(x => x.TableName.Equals(selectedItemValue)).ForeignKeys.ToList();
            comboBoxTransactionItems.DataSource =
                _databaseMetadata.First(x => x.TableName.Equals(selectedItemValue)).ForeignKeys.ToList();
        }

        #region Nested type: DrawForeignKeyGrid

        private delegate void DrawForeignKeyGrid(List<TableForeignKeyData> foreignKeys);

        #endregion

        private void buttonViewResults_Click(object sender, EventArgs e)
        {
            var results = File.ReadAllText(Path.GetTempPath() + _optionsFileReader.Options.TextBoxPath);
            var resultsForm = new ResultsForm(results);
            resultsForm.ShowDialog();            
        }
    }
}